// HTTP请求工具封装
// 基于axios封装，包含请求拦截、响应拦截、token自动刷新等功能
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios' // axios HTTP客户端
import { message, Modal } from 'antd' // Ant Design的消息和弹窗组件

// 创建 axios 实例，配置基础URL和超时时间
const request = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL, // 从环境变量获取API基础URL
  timeout: 10000, // 请求超时时间10秒
  withCredentials: true, // 允许携带cookie
})

// 刷新 token 相关逻辑
let isRefreshing = false // 是否正在刷新token，防止重复刷新
let refreshSubscribers: Array<(token: string) => void> = [] // 等待token刷新的请求队列

// token刷新完成后的回调处理
function onRefreshed(token: string) {
  refreshSubscribers.forEach((cb) => cb(token)) // 通知所有等待的请求
  refreshSubscribers = [] // 清空队列
}

// 添加等待token刷新的订阅者
function addRefreshSubscriber(cb: (token: string) => void) {
  refreshSubscribers.push(cb)
}

// 刷新token的函数
async function refreshToken() {
  const refresh_token = localStorage.getItem('refresh_token') // 从localStorage获取refresh_token
  if (!refresh_token) throw new Error('无refresh_token') // 如果没有refresh_token则抛出错误
  const res = await axios.post('/api/auth/refresh', { refresh_token }) // 调用刷新token接口
  return res.data.token // 返回新的token
}

// 请求拦截器：在请求发送前自动添加token
request.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    const token = localStorage.getItem('token') // 从localStorage获取token
    if (token && config.headers) {
      config.headers['Authorization'] = `Bearer ${token}` // 添加Authorization头
    }
    return config
  },
  (error) => Promise.reject(error) // 请求错误直接拒绝
)

// 响应拦截器：处理响应数据和错误
request.interceptors.response.use(
  (response: AxiosResponse) => {
    // 业务状态码处理
    const { code, message: msg, data } = response.data
    if (code === 200 || code === 0 || response.status === 200) {
      return data ?? response.data // 成功时返回数据
    }
    // 其它业务错误
    message.error(msg || '请求失败') // 显示错误消息
    return Promise.reject(new Error(msg || '请求失败'))
  },
  async (error) => {
    const { response, config } = error
    if (!response) {
      message.error('网络异常，请检查网络连接') // 网络错误提示
      return Promise.reject(error)
    }
    
    // 401 未授权处理：尝试刷新token
    if (response.status === 401) {
      if (!isRefreshing) {
        isRefreshing = true
        try {
          const newToken = await refreshToken() // 刷新token
          localStorage.setItem('token', newToken) // 保存新token
          onRefreshed(newToken) // 通知等待的请求
        } catch (e) {
          // token刷新失败，提示用户重新登录
          Modal.warning({
            title: '登录已过期',
            content: '请重新登录',
            onOk: () => {
              localStorage.removeItem('token') // 清除token
              localStorage.removeItem('refresh_token') // 清除refresh_token
              window.location.href = '/login' // 跳转到登录页
            },
          })
          return Promise.reject(e)
        } finally {
          isRefreshing = false
        }
      }
      // 将当前请求加入等待队列
      return new Promise((resolve) => {
        addRefreshSubscriber((token: string) => {
          if (config.headers) config.headers['Authorization'] = `Bearer ${token}` // 更新请求头
          resolve(request(config)) // 重新发起请求
        })
      })
    }
    
    // 403 权限不足
    if (response.status === 403) {
      message.error('没有权限访问')
    }
    // 404 接口不存在
    if (response.status === 404) {
      message.error('接口不存在')
    }
    // 500 服务器错误
    if (response.status === 500) {
      message.error('服务器错误')
    }
    return Promise.reject(error)
  }
)

export default request 